package com.utn.disenio.entrega2;

import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.Test;
import org.junit.Before;
import org.mockito.Mockito;
import org.mockito.Mockito.*;
import com.lanchita.AerolineaLanchita;
import com.lanchita.excepciones.EstadoErroneoException;
import com.oceanic.AerolineaOceanic;
import com.utn.disenio.entrega3.AerolineaOceanicAdapter;
import com.utn.disenio.entrega3.LlegoElMensajeException;
import com.utn.disenio.entrega3.Viaje;



public class AerolineasTester {

	UsuarioEstandar gabriel;
	UsuarioEstandar mariano;
	UsuarioEstandar bruno;
	UsuarioNoPaga pablo;
	UsuarioNoPaga naomi;
	UsuarioNoPaga julian;
	SistemaAterrizarPuntoCom sistema;
	AerolineaLanchitaAdapter lanchitaAdapter = new AerolineaLanchitaAdapter(); 
	AerolineaLanchita lanchitaMock;
	AerolineaOceanic oceanicMock;
	Asiento elAsiento;
	Asiento elAsientoOceanic;
	AerolineaOceanicAdapter adaptadorOceanic;
	
	@Before
	public void inicializarTest() throws Exception{
		
		sistema = SistemaAterrizarPuntoCom.getInstance();
		lanchitaMock = Mockito.mock(AerolineaLanchita.class);
		sistema.getLanchita().setMock(lanchitaMock);
		oceanicMock = Mockito.mock(AerolineaOceanic.class);
		adaptadorOceanic = new AerolineaOceanicAdapter();
		sistema.getOceanic().setMock(oceanicMock);

		
		elAsientoOceanic = new Asiento("BUE", "LA", "08/05/2012", "09/05/2012", "21:00", "10:05", 5, "1111111", (float) 100, "E", "V", "D", sistema.getOceanic());
		elAsiento = new Asiento("BUE", "LA", "08/05/2012", "09/05/2012", "21:00", "10:05", 5, "1111111", (float) 100, "E", "V", "D", sistema.getLanchita());

		
		mariano = new UsuarioEstandar("Mariano","German","33.333.333");
		gabriel = new UsuarioEstandar("Gabriel","Pan Gantes","44.444.444");
		bruno = new UsuarioEstandar("Bruno","Fischetti","55.555.555");
		pablo = new UsuarioNoPaga("Pablo","Marbian","66.666.666");
		naomi = new UsuarioNoPaga("Naomi","Pasarelli","77.777.777");
		julian = new UsuarioNoPaga("Julius","Larralde","88.888.888");
		mariano.registrarCompra((float)120000); /* Mariano es VIP */

	}
	
	@Test
	public void llegaElMsjCuandoBusco() throws Exception{
			mariano.buscarAsientosDisponibles("EZE", "USA", null, null, null, null, 0,null,null);
		    Mockito.verify(lanchitaMock).asientosDisponibles("EZE", null, null, null, null, null);
		    Mockito.verify(oceanicMock,Mockito.times(1)).asientosDisponiblesParaOrigen("EZE", null);
	}
	

	@Test
	public void leLlegaElMensajeALaAerolineaCuandoCompro() throws Exception{
		mariano.comprarAsiento(elAsiento);
		Mockito.verify(lanchitaMock).comprar("1111111-5");
		mariano.comprarAsiento(elAsientoOceanic);
		Mockito.verify(oceanicMock).comprarSiHayDisponibilidad("33.333.333","1111111", 5);
	}

	
	@Test
	public void agregarUnaSobrereserva() {
		int size = lanchitaAdapter.getAsientosReservados().size();
		Mockito.doThrow(new EstadoErroneoException()).when(lanchitaMock).reservar(Mockito.anyString(), Mockito.anyString());
		mariano.reservarAsiento(elAsiento);
		assertEquals(size++, lanchitaAdapter.getAsientosReservados().size());

	}
	
	
	
	
	
	@Test
	public void marianoEsVip(){
		assertEquals(mariano.getNivel().getClass(), NivelVip.class);
	}
	
	@Test
	public void cuandoCompraMuchoEsVip() throws Exception{
		assertEquals(gabriel.getNivel().getClass() , NivelNormal.class);
		 Mockito.when(lanchitaMock.asientosDisponibles("EZE", null, null , null, null, null)).thenReturn(new String[][] {
	                { "01202022220202-3", "152229.90", "P", "V", "D", "", "14:00","02:25","EZE","USA","20/12/2012","21/12/2012" }});
		ArrayList<Viaje> viajes = new ArrayList<Viaje>();
		viajes.addAll(sistema.buscarAsientos("EZE", "USA", null , null, null, null,0, gabriel,null,null));

		for(Viaje unViaje: viajes)
		{
			gabriel.comprarAsiento(unViaje.getAsientoUno());
			if(unViaje.getAsientoDos() != null)
				gabriel.comprarAsiento(unViaje.getAsientoDos());
			if(unViaje.getAsientoTres() != null)
				gabriel.comprarAsiento(unViaje.getAsientoTres());
		}
	
		assertEquals(gabriel.getNivel().getClass(), NivelVip.class); //No llega a 100.000 los gastos comprados  en asientos
		
	}
	
	@Test(expected = EstadoErroneoException.class)
    public void comprarDosVecesElMismo() throws Exception{   
        Mockito.when(lanchitaMock.asientosDisponibles("EZE", null, null , null, null, null)).thenReturn(new String[][] {
                { "01202022220202-3", "159.90", "P", "V", "D", "", "14:00","02:25","EZE","USA","20/12/2012","21/12/2012" }});
        ArrayList<Viaje> viajes = new ArrayList<Viaje>();
        viajes.addAll(sistema.buscarAsientos("EZE", "USA", null , null, null, null,0, mariano,null,null));
       
        mariano.comprarAsiento(viajes.get(0).getAsientoUno());
        Mockito.doThrow(new EstadoErroneoException()).when(lanchitaMock).comprar(viajes.get(0).getAsientoUno().getCodigoDeVuelo()+"-"+viajes.get(0).getAsientoUno().getNumero());
        gabriel.comprarAsiento(viajes.get(0).getAsientoUno());
    }
	
	@Test
	public void aumentanSusComprasTotales() throws Exception {
		
		float gastosAnteriores = mariano.getGastosAcumulados();
		Mockito.when(lanchitaMock.asientosDisponibles("EZE", null, null , null, null, null)).thenReturn(new String[][] {
	                { "01202022220202-3", "152229.90", "P", "V", "D", "", "14:00","02:25","EZE","USA","20/12/2012","21/12/2012" }});
		ArrayList<Viaje> viajes = new ArrayList<Viaje>();
		viajes.addAll(sistema.buscarAsientos("EZE", "USA", null , null, null, null,0, mariano,null,null));

		for(Viaje unViaje: viajes)
		{
			mariano.comprarAsiento(unViaje.getAsientoUno());
			if(unViaje.getAsientoDos() != null)
				mariano.comprarAsiento(unViaje.getAsientoDos());
			if(unViaje.getAsientoTres() != null)
				mariano.comprarAsiento(unViaje.getAsientoTres());
		}
		
		float gastosActuales = mariano.getGastosAcumulados();
		
		assertTrue(gastosAnteriores < gastosActuales);
	}
	
	
	

	
	
	
	
	
	
}
